package com.yihusitian.zsxq.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.yihusitian.zsxq.constant.BusinessConstant;
import com.yihusitian.zsxq.pojo.data.TopicDO;
import com.yihusitian.zsxq.pojo.dto.Resp;
import com.yihusitian.zsxq.pojo.dto.Topic;
import com.yihusitian.zsxq.service.DataBuildService;
import com.yihusitian.zsxq.service.TopicService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @Author LeeHo
 * @Date 2021/3/25 11:51
 */
@Slf4j
@Service
public class DataBuildServiceImpl implements DataBuildService {

    @Autowired
    private TopicService topicService;

    @Override
    public void buildData() {
        List<File> files = this.listFiles();
        if (CollectionUtil.isNotEmpty(files)) {
            List<Topic> topics = files.stream().map(file -> {
                Resp resp = this.toResp(file);
                return resp;
            }).filter(item -> item != null && item.getResp_data() != null && item.getResp_data().getTopic() != null)
                    .map(resp -> resp.getResp_data().getTopic()).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(topics)) {
                if (topics.size() < 10) {
                    topics.forEach(topic -> {
                        topicService.createTopic(topic);
                    });
                    return;
                }
                int processors = Runtime.getRuntime().availableProcessors();
                ExecutorService executorService = Executors.newFixedThreadPool(processors);
                CountDownLatch countDownLatch = new CountDownLatch(processors);
                int pageSize = topics.size() / processors;
                if (topics.size() % processors != 0) {
                    pageSize++;
                }
                List<List<Topic>> topicPartitionList = Lists.partition(topics, pageSize);
                for(List<Topic> list : topicPartitionList) {
                    executorService.execute(new Runnable() {
                        @Override
                        public void run() {
                            list.forEach(topic -> topicService.createTopic(topic));
                            countDownLatch.countDown();
                        }
                    });
                }
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    executorService.shutdown();
                }
                log.info("所有Topic处理完成！topics.size:{}, thread.count:{}", topics.size(), processors);
            }
        }
    }
    /**
     *
     * @return
     */
    private List<File> listFiles() {
        List<File> files = FileUtil.loopFiles(BusinessConstant.OLD_STORAGE_PATH);
        List<TopicDO> taskTopicList = topicService.list(new LambdaQueryWrapper<TopicDO>().eq(TopicDO::getType, "task"));
        Set<String> fileNames = taskTopicList.stream().map(item -> item.getId() + ".txt").collect(Collectors.toSet());
        if (CollectionUtil.isNotEmpty(files)) {
            files = files.stream().filter(item -> fileNames.contains(item.getName())).collect(Collectors.toList());
//            files = files.stream().filter(item -> item.getName().endsWith("txt")).collect(Collectors.toList());
            files.stream().forEach(file -> System.out.println(file.getName()));
        }
        return files;
    }

    /**
     * 对象转换
     *
     * @param file
     * @return
     */
    private Resp toResp(File file) {
        try {

            String content = FileUtil.readUtf8String(file);
            log.info("文件{}内容:{}", file.getName(), content);
            return JSONObject.parseObject(content, Resp.class);
        } catch (Exception e) {
            log.error("文件{}转换Resp对象异常", file.getName(), e);
        }
        return null;
    }

    /**
     * 对象转换
     *
     * @param file
     * @return
     */
    private Topic toTopic(File file) {
        try {
            String content = FileUtil.readUtf8String(file);
            log.info("文件{}内容:{}", file.getName(), content);
            return JSONObject.parseObject(content, Topic.class);
        } catch (Exception e) {
            log.error("文件{}转换Topic对象异常", file.getName(), e);
        }
        return null;
    }
}